!pr0
!lm12
!rm75
An "ORG" Macro for Self-Aligning Code......Bob Sander-Cederlof

Roger Johnson (Minnesota) called a week or so ago with a plea for an easy way to make program segments align themselves automatically on page boundaries.  He was writing a system to be burned into EPROM and run on another computer; it would be easier to debug in the target machine if subroutines and data blocks began on even page boundaries.  There was ample room, so the wasted bytes between routines didn't bother him.

Of course, the .OR directive in the S-C Macro Assembler can easily change the origin whenever you wish, but it also changes the target address (.TA directive) or closes any open target file (.TF directive).  Therefore a different approach is required.

Bill Morgan and Mike Laumer described how to do this in these pages a few months back, using the .BS directive to reserve enough bytes to reach the next page boundary.  But with the help of a simple macro, we can not only make it easier to make self-aligning code:  we can also make it generate error messages if the origin we try to set involves backing up over a longer-than-expected predecessor.

Here is the macro definition, and a few lines demonstrating how to call the macro:

!lm+5
1000        .MA ORG
1010        .DO *>]1
1020  !!! ERROR: ORG ]1 RANGE CROSSED !!!
1030        .ELSE
1040        .BS ]1-*
1050        .FIN
1060        .EM
1070 *--------------------------------
1080        .OR $800
1090 SAMPLE LDA $1234
1100        RTS
1110        >ORG $900
1120        STA $1234
1130        RTS
1140        >ORG $980
1150 DATA   .DA #1,#2,#3
!lm-5

Line 1110 calls the ORG macro with a parameter of "$900".  This means that everywhere you find "]1" in the macro definition, the assembler will see "$900".  The conditional (.DO) on line 1010 will read ".DO *>$900".  Since * equals $804 at this point, it is not greater than $900.  Therefore the condition is false, and the lines following line 1010 will be skipped up to line 1030 where there is an ".ELSE".  The lines after 1030 through the ".FIN" on line 1050 will be assembled.  Line 1040 will be assembled as ".BS $900-*", which will bump the location up to $900.
!np
Here's how the above example assembles:

!lm+5
               1000        .MA ORG
               1010        .DO *>]1
               1020  !!! ERROR: ORG ]1 RANGE CROSSED !!!
               1030        .ELSE
               1040        .BS ]1-*
               1050        .FIN
               1060        .EM
               1070 *--------------------------------
               1080        .OR $800
0800- AD 34 12 1090 SAMPLE LDA $1234
0803- 60       1100        RTS
0804-          1110        >ORG $900
               0000>        .DO *>$900
               0000>        .ELSE
0804-          0000>        .BS $900-*
               0000>        .FIN
0900- 8D 34 12 1120        STA $1234
0903- 60       1130        RTS
0904-          1140        >ORG $980
               0000>        .DO *>$980
               0000>        .ELSE
0904-          0000>        .BS $980-*
               0000>        .FIN
0980- 01 02 03 1150 DATA   .DA #1,#2,#3
!lm-5

If we had written line 1110 as ">ORG $800" the condition on line 1010 would be true, causing line 1020 to be assembled.  Line 1020 is illegal syntax for the assembler, so it will be listed after an error message.  The "]1" will be filled in to make the line list like this:

     *** BAD OPCODE ERROR
      1110>  !!! ERROR: ORG $800 RANGE CROSSED !!!

That will occur during pass one of the assembly, so no code will be generated.  The error message will be the only output.
